package actions

import (
	"fmt"
	"strings"

	"github.com/nyaruka/gocommon/urns"
	"github.com/nyaruka/goflow/flows"
	"github.com/nyaruka/goflow/flows/events"
	"github.com/nyaruka/goflow/flows/modifiers"
)

func init() {
	registerType(TypeAddContactURN, func() flows.Action { return &AddContactURNAction{} })
}

// TypeAddContactURN is our type for the add URN action
const TypeAddContactURN string = "add_contact_urn"

// AddContactURNAction can be used to add a URN to the current contact. A [event:contact_urns_changed] event
// will be created when this action is encountered.
//
//	{
//	  "uuid": "8eebd020-1af5-431c-b943-aa670fc74da9",
//	  "type": "add_contact_urn",
//	  "scheme": "tel",
//	  "path": "@results.phone_number.value"
//	}
//
// @action add_contact_urn
type AddContactURNAction struct {
	baseAction
	universalAction

	Scheme string `json:"scheme" validate:"urnscheme"`
	Path   string `json:"path" validate:"required" engine:"evaluated"`
}

// NewAddContactURN creates a new add URN action
func NewAddContactURN(uuid flows.ActionUUID, scheme string, path string) *AddContactURNAction {
	return &AddContactURNAction{
		baseAction: newBaseAction(TypeAddContactURN, uuid),
		Scheme:     scheme,
		Path:       path,
	}
}

// Execute runs the labeling action
func (a *AddContactURNAction) Execute(run flows.Run, step flows.Step, logModifier flows.ModifierCallback, logEvent flows.EventCallback) error {
	evaluatedPath, _ := run.EvaluateTemplate(a.Path, logEvent)
	evaluatedPath = strings.TrimSpace(evaluatedPath)
	if evaluatedPath == "" {
		logEvent(events.NewErrorf("can't add URN with empty path"))
		return nil
	}

	// create URN - modifier will take care of validating it
	urn := urns.URN(fmt.Sprintf("%s:%s", a.Scheme, evaluatedPath))

	a.applyModifier(run, modifiers.NewURNs([]urns.URN{urn}, modifiers.URNsAppend), logModifier, logEvent)
	return nil
}
